home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / General / SC++ 7.0.2 Update / TCL Demos / Art Class ƒ / Art Class Sources / CToolPens.cp < prev   
Encoding:
Text File  |  1994-04-14  |  11.7 KB  |  415 lines  |  [TEXT/KAHL]

  1. /******************************************************************************
  2.  CToolPens.c
  3.  
  4.                             The ToolPens Class
  5.         
  6.     SUPERCLASS = CPaintTask
  7.     
  8.     Copyright © 1989 Symantec Corporation. All rights reserved.
  9.  
  10.  ******************************************************************************/
  11.  
  12. #include "Global.h"
  13. #include "TBUtilities.h"
  14. #include "CToolPens.h"
  15.  
  16. extern RgnHandle    gUtilRgn;            /* Utility region                    */
  17.  
  18. extern CBitMap        *gScratchPad;
  19. extern Pattern        gPattern;            /* The current fill pattern            */
  20. extern short        gLineSize;
  21.  
  22. #define        SHIFTKEY_CODE    0x38        /* Hardware code for the shift key    */
  23. #define        iPAINTING        7            /* Index for Painting task name        */
  24. #define        iERASER            8            /* Index for Erase task name        */
  25. #define        iPENCIL            9            /* Index for Pencil task name        */
  26.  
  27. #define        ERASER_LENGTH    16            /* Size of eraser in pixels            */
  28. #define        BRUSH_LENGTH    4            /* Size of brush in pixels            */
  29.  
  30.  
  31. /**** C O N S T R U C T I O N / D E S T R U C T I O N   M E T H O D S ****/
  32.  
  33.  
  34. /******************************************************************************
  35.  CToolPens
  36.  ******************************************************************************/
  37.  
  38. CToolPens::CToolPens(short aNameIndex, CPaintPane *aPaintPane,CBitMap *aPainting) 
  39.          : CPaintTask(aNameIndex, aPaintPane, aPainting)
  40. {}
  41.  
  42.  
  43. /******************************************************************************
  44.  BeginTracking {OVERRIDE}
  45.  
  46.         Mouse down tracking is about to begin at the specified starting
  47.         point. Set the pen size and fill pattern.
  48.  ******************************************************************************/
  49.  
  50. void    CToolPens::BeginTracking(
  51.     LongPt        *startPt)
  52. {
  53.                                         /* Copy entire image to scratch pad    */
  54.     CopyBits(itsPainting->macBitMap, gScratchPad->macBitMap,
  55.              &itsPainting->macBitMap->bounds, &itsPainting->macBitMap->bounds,
  56.              srcCopy, NULL);
  57.              
  58.     PenNormal();
  59. }
  60.  
  61.  
  62. /******************************************************************************
  63.  KeepTracking {OVERRIDE}
  64.  
  65.         Continuous mouse tracking while the mouse button is down. Draw
  66.         only when the mouse moves or the panorama autoscrolls.
  67.  ******************************************************************************/
  68.  
  69. void    CToolPens::KeepTracking(
  70.     LongPt        *currPt,
  71.     LongPt        *prevPt,
  72.     LongPt        *startPt)
  73. {
  74.     LongRect        currRect;
  75.  
  76.     if (itsPaintPane->AutoScroll(currPt) || !EqualLongPt(currPt, prevPt)) {
  77.         itsPaintPane->GetFrame(&currRect);
  78.         PinInRect(&currRect, currPt);
  79.         UseTool(currPt, prevPt);
  80.     }
  81. }
  82.  
  83.  
  84. /******************************************************************************
  85.  CalcPenRect
  86.  
  87.         Calculate the rectangle affected by a pen tool located at a
  88.         specified point
  89.  ******************************************************************************/
  90.  
  91. void    CToolPens::CalcPenRect(
  92.     LongPt        *thePt,
  93.     LongRect    *penRect)
  94. {
  95.     penRect->left = thePt->h;            /* Pen hangs below and to the right    */
  96.     penRect->top = thePt->v;            /*   of its coordinate location        */
  97.     penRect->right = thePt->h + penLength;
  98.     penRect->bottom = thePt->v + penLength;
  99. }
  100.  
  101.  
  102. /******************************************************************************
  103.  CalcDirtyRect
  104.  
  105.         Calculate the portion of the image drawn on by a pen. Find the
  106.         rectangle which encloses the current dirtyRect and the current
  107.         pen rectangle.
  108.  ******************************************************************************/
  109.  
  110. void    CToolPens::CalcDirtyRect(
  111.     LongRect        *penRect)
  112. {
  113.     dirtyRect.left = Min(dirtyRect.left, penRect->left);
  114.     dirtyRect.top = Min(dirtyRect.top, penRect->top);
  115.     dirtyRect.right = Max(dirtyRect.right, penRect->right);
  116.     dirtyRect.bottom = Max(dirtyRect.bottom, penRect->bottom);
  117. }
  118.  
  119.  
  120. /******************************************************************************
  121.  CalcDrawRgn
  122.  
  123.         Calculate the draw region affected by a pen. What a pain. We have
  124.         to tweak the region depending on where the current point is in
  125.         relation to the previous point because the pen hangs below and
  126.         to the right of its location.
  127.  ******************************************************************************/
  128.  
  129. void    CToolPens::CalcDrawRgn(
  130.     LongRect    *currRect,
  131.     LongRect    *prevRect,
  132.     RgnHandle    drawRgn)
  133. {
  134.     OpenRgn();
  135.     
  136.     if (currRect->left > prevRect->left) {
  137.         if (currRect->top > prevRect->top) {
  138.             LMoveTo(currRect->right, currRect->top);
  139.             LLineTo(currRect->right, currRect->bottom);
  140.             LLineTo(currRect->left, currRect->bottom);
  141.             LLineTo(prevRect->left, prevRect->bottom);
  142.             LLineTo(prevRect->left, prevRect->top);
  143.             LLineTo(prevRect->right, prevRect->top);
  144.             LLineTo(currRect->right, currRect->top);
  145.         
  146.         } else {
  147.             LMoveTo(currRect->left, currRect->top);
  148.             LLineTo(currRect->right, currRect->top);
  149.             LLineTo(currRect->right, currRect->bottom);
  150.             LLineTo(prevRect->right, prevRect->bottom);
  151.             LLineTo(prevRect->left, prevRect->bottom);
  152.             LLineTo(prevRect->left, prevRect->top);
  153.             LLineTo(currRect->left, currRect->top);
  154.         }
  155.         
  156.     } else {
  157.         if (currRect->top > prevRect->top) {
  158.             LMoveTo(currRect->right, currRect->bottom);
  159.             LLineTo(currRect->left, currRect->bottom);
  160.             LLineTo(currRect->left, currRect->top);
  161.             LLineTo(prevRect->left, prevRect->top);
  162.             LLineTo(prevRect->right, prevRect->top);
  163.             LLineTo(prevRect->right, prevRect->bottom);
  164.             LLineTo(currRect->right, currRect->bottom);
  165.         
  166.         } else {
  167.             LMoveTo(currRect->left, currRect->bottom);
  168.             LLineTo(currRect->left, currRect->top);
  169.             LLineTo(currRect->right, currRect->top);
  170.             LLineTo(prevRect->right, prevRect->top);
  171.             LLineTo(prevRect->right, prevRect->bottom);
  172.             LLineTo(prevRect->left, prevRect->bottom);
  173.             LLineTo(currRect->left, currRect->bottom);
  174.         }
  175.     }
  176.     
  177.     CloseRgn(drawRgn);
  178. }
  179.  
  180.  
  181. /******************************************************************************
  182.  EndTracking {OVERRIDE}
  183.  
  184.         Mouse down tracking has ended because the user has released the
  185.         mouse button. Its now time to set up the undo buffer and change
  186.         the actual offscreen painting image.
  187.  ******************************************************************************/
  188.  
  189. void    CToolPens::EndTracking(
  190.     LongPt        *currPt,
  191.     LongPt        *prevPt,
  192.     LongPt        *startPt)
  193. {
  194.                                     /* Track for the last time                */
  195.     KeepTracking(currPt, prevPt, startPt);
  196.     
  197.                                     /* Create an undo bitmap                */
  198.     itsUndoBits = new CBitMap(dirtyRect.right  - dirtyRect.left,
  199.                               dirtyRect.bottom - dirtyRect.top, FALSE);
  200.     
  201.     if (itsUndoBits->macBitMap == NULL) {
  202.          TCLForgetObject(itsUndoBits);        // couldn't allocate bitmap?  KI 2/17/94
  203.     } else {
  204.         itsUndoBits->SetBoundsOrigin(dirtyRect.left, dirtyRect.top);
  205.         
  206.                                     /* Original image is on the scratchpad    */
  207.                                     /* Copy dirty area to undo bitmap        */
  208.         LCopyBits(gScratchPad->macBitMap, itsUndoBits->macBitMap,
  209.                     &dirtyRect, &dirtyRect, srcCopy, NULL);
  210.     }
  211. }
  212.  
  213.  
  214. /******************************************************************************
  215.  UseTool
  216.  ******************************************************************************/
  217.  
  218. void    CToolPens::UseTool(
  219.     LongPt        *currPt,
  220.     LongPt        *prevPt)
  221. {
  222. }                                    /* Null Method                            */
  223.  
  224.  
  225. /**** Methods for Different Pen Tools ****/
  226.  
  227.  
  228. /******************************************************************************
  229.  CToolEraser {Eraser}
  230.  ******************************************************************************/
  231.  
  232. CToolEraser::CToolEraser(CPaintPane    *aPaintPane,CBitMap    *aPainting)
  233.            : CToolPens(iERASER, aPaintPane, aPainting)
  234. {
  235.     penLength = ERASER_LENGTH;
  236. }
  237.  
  238.  
  239. /******************************************************************************
  240.  BeginTracking {Eraser}
  241.  ******************************************************************************/
  242.  
  243. void    CToolEraser::BeginTracking(
  244.     LongPt        *startPt)
  245. {
  246.     LongRect        r;
  247.  
  248.     CToolPens::BeginTracking(startPt);
  249.     
  250.     CalcPenRect( startPt, &r);
  251.     dirtyRect = r;
  252.     
  253.     LEraseRect(&r);                        /* Do erasure on screen                */
  254.     
  255.     itsPainting->BeginDrawing();        /* Do erasure on offscreen bitmap    */
  256.     LEraseRect(&r);
  257.     itsPainting->EndDrawing();
  258. }
  259.  
  260.  
  261. /******************************************************************************
  262.  UseTool {Eraser}
  263.  ******************************************************************************/
  264.  
  265. void    CToolEraser::UseTool(
  266.     LongPt        *currPt,
  267.     LongPt        *prevPt)
  268. {
  269.     LongRect        currRect;
  270.     LongRect        prevRect;
  271.     
  272.     CalcPenRect( currPt, &currRect);
  273.     CalcPenRect( prevPt, &prevRect);
  274.     
  275.     CalcDirtyRect(&currRect);            /* Determine changed area            */
  276.     CalcDrawRgn(&currRect, &prevRect, gUtilRgn);
  277.     
  278.     EraseRgn(gUtilRgn);                    /* Do erasure on screen                */
  279.     
  280.     itsPainting->BeginDrawing();        /* Do erasure on offscreen bitmap    */
  281.     EraseRgn(gUtilRgn);
  282.     itsPainting->EndDrawing();
  283. }
  284.  
  285.  
  286. /******************************************************************************
  287.  IToolPencil {Pencil}
  288.  ******************************************************************************/
  289.  
  290. CToolPencil::CToolPencil(CPaintPane    *aPaintPane,CBitMap    *aPainting)
  291.            : CToolPens(iPENCIL, aPaintPane, aPainting)
  292. {
  293.     penLength = 1;
  294. }
  295.  
  296.  
  297. /******************************************************************************
  298.  BeginTracking {Pencil}
  299.  ******************************************************************************/
  300.  
  301. void    CToolPencil::BeginTracking(
  302.     LongPt        *startPt)
  303. {
  304.     LongRect    r;
  305.     Pattern        thePenPat;
  306.  
  307.     CToolPens::BeginTracking(startPt);
  308.     
  309.     CalcPenRect( startPt, &r);
  310.     dirtyRect = r;
  311.     
  312.     PenNormal();                        /* Start with a normal pen            */
  313.     if (itsPainting->PixelIsBlack( startPt)) {
  314.                                         /* Pencil is on a black pixel        */
  315.                                         /*   Subsequent drawing will create    */
  316.                                         /*   white pixels                    */
  317.         BlockMove(&qd.white, &thePenPat, 8);
  318.         
  319.     } else {                            /* Pencil is on a white pixel        */
  320.                                         /*   Subsequent drawing will create    */
  321.                                         /*   black pixels                    */
  322.         BlockMove(&qd.black, &thePenPat, 8);
  323.     }
  324.  
  325.     PenPat(&thePenPat);                    /* Do drawing on screen                */
  326.     LMoveTo(startPt->h, startPt->v);
  327.     Line(0,0);
  328.     
  329.     itsPainting->BeginDrawing();        /* Do drawing on offscreen bitmap    */
  330.     PenPat(&thePenPat);
  331.     LMoveTo(startPt->h, startPt->v);
  332.     Line(0,0);
  333.     itsPainting->EndDrawing();
  334. }
  335.  
  336.  
  337. /******************************************************************************
  338.  UseTool {Pencil}
  339.  ******************************************************************************/
  340.  
  341. void    CToolPencil::UseTool(
  342.     LongPt        *currPt,
  343.     LongPt        *prevPt)
  344. {
  345.     LongRect    currRect;
  346.  
  347.     CalcPenRect( currPt, &currRect);    /* Determine changed area            */
  348.     CalcDirtyRect(&currRect);
  349.     
  350.     LMoveTo(prevPt->h, prevPt->v);        /* Do drawing on screen                */
  351.     LLineTo(currPt->h, currPt->v);
  352.     
  353.     itsPainting->BeginDrawing();        /* Do drawing on offscreen bitmap    */
  354.     LMoveTo(prevPt->h, prevPt->v);
  355.     LLineTo(currPt->h, currPt->v);
  356.     itsPainting->EndDrawing();
  357. }
  358.  
  359.  
  360. /******************************************************************************
  361.  CToolBrush {Paint Brush}
  362.  ******************************************************************************/
  363.  
  364. CToolBrush::CToolBrush(CPaintPane *aPaintPane,CBitMap *aPainting)
  365.           : CToolPens(iPAINTING, aPaintPane, aPainting)
  366. {
  367.     penLength = BRUSH_LENGTH;
  368. }
  369.  
  370.  
  371. /******************************************************************************
  372.  BeginTracking {Paint Brush}
  373.  ******************************************************************************/
  374.  
  375. void    CToolBrush::BeginTracking(
  376.     LongPt        *startPt)
  377. {
  378.     LongRect    r;
  379.  
  380.     CToolPens::BeginTracking(startPt);
  381.     
  382.     CalcPenRect( startPt, &r);
  383.     dirtyRect = r;
  384.     
  385.     LFillRect(&r, &gPattern);                /* Do painting on screen            */
  386.     
  387.     itsPainting->BeginDrawing();        /* Do painting on offscreen bitmap    */
  388.     LFillRect(&r, &gPattern);
  389.     itsPainting->EndDrawing();
  390. }
  391.  
  392.  
  393. /******************************************************************************
  394.  UseTool {Paint Brush}
  395.  ******************************************************************************/
  396.  
  397. void    CToolBrush::UseTool(
  398.     LongPt        *currPt,
  399.     LongPt        *prevPt)
  400. {
  401.     LongRect    currRect;
  402.     LongRect    prevRect;
  403.     
  404.     CalcPenRect( currPt, &currRect);
  405.     CalcPenRect( prevPt, &prevRect);
  406.     
  407.     CalcDirtyRect(&currRect);            /* Determine changed area            */
  408.     CalcDrawRgn(&currRect, &prevRect, gUtilRgn);
  409.     
  410.     FillRgn(gUtilRgn, &gPattern);        /* Do painting on screen            */
  411.     
  412.     itsPainting->BeginDrawing();        /* Do painting on offscreen bitmap    */
  413.     FillRgn(gUtilRgn, &gPattern);
  414.     itsPainting->EndDrawing();
  415. }